package com.biz.primus.ms.member.service;

import com.biz.primus.base.exception.BizBusinessException;
import com.biz.primus.base.exception.BizParameterException;
import com.biz.primus.model.member.exception.UserException;
import com.biz.primus.model.member.exception.UserExceptionType;
import com.biz.primus.model.member.enums.InvoiceTypes;
import com.biz.primus.model.member.vo.MemberInvoiceVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.member.dao.po.MemberInvoice;
import com.biz.primus.ms.member.dao.redis.MemberInvoiceRedisDao;
import com.biz.primus.ms.member.dao.repository.MemberInvoiceRepository;
import com.biz.primus.ms.member.dao.ro.MemberInvoiceRo;
import com.biz.primus.ms.member.dao.ro.MemberRo;
import com.biz.primus.ms.member.trans.MemberInvoiceToMemberInvoiceRo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 发票
 * @author jun.liu
 * @date 2017年10月23日
 * @reviewer
 * @see
 */
@Slf4j
@Service
public class MemberInvoiceService extends AbstractBaseService
{
    private final MemberInvoiceRedisDao memberInvoiceRedisDao;

    private final MemberInvoiceRepository memberInvoiceRepository;

    private final MemberService memberService;

    @Autowired
    public MemberInvoiceService(MemberInvoiceRedisDao memberInvoiceRedisDao, MemberInvoiceRepository memberInvoiceRepository,
                                MemberService memberService)
    {
        this.memberInvoiceRedisDao = memberInvoiceRedisDao;
        this.memberInvoiceRepository = memberInvoiceRepository;
        this.memberService = memberService;
    }

    /**
     * 保存或者修改发票对象
     * @param vo
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(MemberInvoiceVo vo)
    {
        if (vo == null)
        {
            throw new UserException(UserExceptionType.PARAMS_ERROR);
        }
        if (vo.getMemberId() == null)
        {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        if (vo.getInvoiceTitle() == null)
        {
            throw new UserException(UserExceptionType.INVOICE_TITLE_NULL);
        }
        if (vo.getInvoiceType() == null)
        {
            throw new UserException(UserExceptionType.INVOICE_TYPE_NULL);
        }
        if(vo.getInvoiceType() == InvoiceTypes.company && StringUtils.isBlank(vo.getIdentifierNumber())) {
            throw new UserException(UserExceptionType.INVOICE_IDEN_NULL);
        }
        MemberRo memberRo = this.memberService.findRoById(vo.getMemberId());
        List<MemberInvoice> invoices = this.memberInvoiceRepository.findByInvoiceTypeAndMemberId(vo.getInvoiceType(), memberRo.getId());
        if(invoices != null && !invoices.isEmpty())
        {
            List<MemberInvoice> saveInvoicePos = new ArrayList<>();
            boolean flag = false;
            for(MemberInvoice invoice : invoices)
            {
                if(invoice.getInvoiceTitle().equals(vo.getInvoiceTitle()))
                {
                    BeanUtils.copyProperties(vo, invoice);
                    if(invoice.getSelectDefault())
                    {
                        flag = true;
                    }
                    saveInvoicePos.add(invoice);
                }
                else
                {
                    if(flag)
                    {
                        invoice.setSelectDefault(false);
                        saveInvoicePos.add(invoice);
                    }
                }
            }
            batchSaveOrUpdateUsingPoPKIncreament(memberInvoiceRepository, memberInvoiceRedisDao, saveInvoicePos, new MemberInvoiceToMemberInvoiceRo());
        }
        else
        {
            MemberInvoice po = new MemberInvoice();
            BeanUtils.copyProperties(vo, po);
            saveOrUpdateUsingPoPKIncreament(memberInvoiceRepository, memberInvoiceRedisDao, po, new MemberInvoiceToMemberInvoiceRo());
        }

    }

    /**
     * 根据id获取po
     * @param id
     * @return
     */
    public  MemberInvoice findPoById(Long id)
    {
        if (id == null || id == 0L)
        {
            throw new BizParameterException("id Parameter is null");
        }
        MemberInvoice po = memberInvoiceRepository.findOne(id);
        if (po == null)
        {
            throw new BizBusinessException("MemberInvoice result is null");
        }
        return po;
    }

    /**
     * 根据id获取ro
     * @param id
     * @return
     */
    public MemberInvoiceRo findRoById(Long id)
    {
        if (id == null || id == 0L)
        {
            throw new UserException(UserExceptionType.ID_ERROR);
        }
        MemberInvoiceRo ro = memberInvoiceRedisDao.findOne(id);
        if (ro == null)
        {
           return null;
        }
        return ro;
    }

    /**
     * 根据id获取vo
     * @param id
     * @return
     */
    public MemberInvoiceVo findVoById(Long id)
    {
        if (id == null || id == 0L)
        {
            return null;
        }
        MemberInvoiceRo ro = findRoById(id);
        MemberInvoiceVo vo = new MemberInvoiceVo();
        BeanUtils.copyProperties(ro, vo);
        return vo;
    }

    /**
     * 根据memberId获取pos
     * @param invoiceType
     * @param memberId
     * @return
     */
    public List<MemberInvoice> findPosByMemberId(InvoiceTypes invoiceType, Long memberId)
    {
        if (memberId == null || memberId == 0L) {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        List<MemberInvoice> pos = memberInvoiceRepository.findByInvoiceTypeAndMemberId(invoiceType, memberId);
        if (pos == null)
        {
            pos = new ArrayList<>();
        }
        return pos;
    }

    /**
     * 根据memberId获取vos
     * @param invoiceType
     * @param memberId
     * @return
     */
    public List<MemberInvoiceVo> findVosByMemberId(InvoiceTypes invoiceType, Long memberId)
    {
        if (memberId == null || memberId == 0L) {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        List<MemberInvoiceVo> vos = new ArrayList<>();
        List<MemberInvoice> pos = findPosByMemberId(invoiceType, memberId);
        for(MemberInvoice po : pos)
        {
            MemberInvoiceVo vo = new MemberInvoiceVo();
            BeanUtils.copyProperties(po, vo);
            vos.add(vo);
        }
        return vos;
    }

    /**
     * 根据id删除
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void delById(Long id)
    {
        if (id == null || id == 0L)
        {
            throw new UserException(UserExceptionType.ID_ERROR);
        }
        this.deleteEntity(memberInvoiceRepository, memberInvoiceRedisDao, id);
    }
}
